package com.onpositive.knowledge.model.value.audits;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Set;

import com.onpositive.data.IPropertyConstants;
import com.onpositive.knowledge.model.IUniverse;
import com.onpositive.semantic.model.api.meta.DefaultMetaKeys;
import com.onpositive.semantic.model.api.property.IProperty;
import com.onpositive.semantic.model.api.property.PropertyAccess;


public class AllPropertiesAudit extends AuditSourceContainer implements IUniverseAudit{

	/**
	 * 
	 */
	private CompositeAudit compositeValueAuditAudit ;
	
	private static final long serialVersionUID = 1L;

	public static final String ID = "all-properties-audit" ;
	
	public AllPropertiesAudit() {
		super();
	}

	public void perform( Iterable<IProperty> _properties, Iterable<Object> objects, AbstractAuditResult auditResult ) {
		
		if( !( auditResult instanceof GeneralAuditResult) )
			return ;
		
		GeneralAuditResult rd = (GeneralAuditResult) auditResult ;
		
		Iterable<IProperty> properties = _properties != null ? _properties : getUniverse().getProperties( null ) ;
		
		for (IProperty m:properties)
		{
			//FIXME
			if(m.getId().equals(IPropertyConstants.EXTERNAL_DEFAULT_PICTURE_PROPERTY_NAME)){
				continue;
			}
			IValueAudit service = DefaultMetaKeys.getService(m,IValueAudit.class);
			if (service!=null)
				applyAudit(service, m, rd, objects);				
		}
		
		if (compositeValueAuditAudit!=null)
			applyAudit( compositeValueAuditAudit, properties, rd, objects);

	}

	@Override
	public AbstractAuditResult createAuditResult() {
		return new GeneralAuditResult( null );
	}

	protected void applyAudit(IValueAudit valueAudit, IProperty m,	GeneralAuditResult rd, Iterable<Object> objects)
	{
		AbstractAuditResult auditResult = valueAudit.createAuditResult(m) ;
		if( auditResult == null )
			return ;
		
		valueAudit.perform(m, objects, auditResult);		
		
		if (auditResult.isLooksApplyable()){
			rd.addChildAudit(auditResult);
			rd.looksApplyable=true;
		}
	}
	
	protected void applyAudit( IUniverseAudit universeAudit, Iterable<IProperty> m, GeneralAuditResult rd, Iterable<Object> objects)
	{
		AbstractAuditResult auditResult = universeAudit.createAuditResult() ;
		rd.addChildAudit(auditResult);
		universeAudit.perform(m, objects, auditResult);
		if( auditResult == null )
			return ;
		
		if (!auditResult.isLooksApplyable())			
			rd.removeChildAudit(auditResult) ;
		else
			rd.looksApplyable=true;
	}
	
	public void addAudit( IAudit va )
	{
		if( compositeValueAuditAudit == null )
			compositeValueAuditAudit = new CompositeAudit() ;
		
		compositeValueAuditAudit.add(va) ;
	}
	
	public void removeAudit( IValueAudit va )
	{
		if( compositeValueAuditAudit == null )
			return ;
		
		compositeValueAuditAudit.remove(va) ;
	}

	@Override
	public String getId() {
		
		return ID;
	}

	public CompositeAudit getCompositeValueAuditAudit() {
		
		if( compositeValueAuditAudit == null )
			compositeValueAuditAudit = new CompositeAudit() ;
		
		return compositeValueAuditAudit;
	}

	@Override
	public Set<String> getRequiredAudits() {
		// TODO Auto-generated method stub
		return null;
	}
}
